%{
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#define YYSTYPE double
extern void yyerror(char const *s);

int Max_top = 100;
int Max_length_of_string = 10000;
int min_top = 0;
struct _stack{
    int top;
    char data[100][10000];
};

typedef struct _stack _stack;
void init_stack(_stack *stack){
    int i;
    stack->top = min_top-1;
    for(i = 0; i < Max_top; i++)
        memset(stack->data[i], 0, sizeof(char) * Max_length_of_string);
}
int push_to_stack(_stack *stack, char *InItem){
    stack->top++;
    if(stack->top > Max_top-1)
        return 1;
    sprintf(stack->data[stack->top], "%s", InItem);
    return 0;
}
int pop_from_stack(_stack *stack, char *OutItem){
    if(stack->top < min_top)
        return 1;
    sprintf(OutItem, "%s", stack->data[stack->top--]);
    return 0;
}
 int i;
 int array_size;
_stack arith;
_stack var;
_stack assign;
_stack logic_stack;
_stack expr_stack;
_stack atrb;
_stack arg;
_stack declaration;
_stack type;
_stack block_stack;
_stack block_l_stack;
_stack stat;
_stack stat_l;
_stack stat_c;
_stack stat_j;
_stack stat_s_stack;
_stack expr_s_stack;
_stack stat_i_stack;
_stack declaration_l;
_stack fun;
_stack fun_l;
_stack param;
_stack param_l;
_stack return_t;

char tmp1[10000];
char tmp2[10000];
char tmp3[10000];
char tmp4[10000];
char tmp5[10000];
char array_id[10000];
char * token;
%}
%token NUMBER DIST POSITION DIRECTION DISTANCE CONSTANT IDENTIFIER ATTRIBUTE RETURN
%token NL  OR_OP AND_OP EQ_OP NE_OP GE_OP LE_OP TYPE IF ELSE FOR STRING_LITERAL EF
%left OR_OP
%left AND_OP
%left EQ_OP NE_OP
%left '>' '<' GE_OP LE_OP
%left '+' '-'
%left '*' '/' '%'
%right UMINUS

%%

lines :   function_definition_list ';'   {   memset(tmp1, 0, sizeof(char)*Max_length_of_string);
			    pop_from_stack(&fun_l, tmp1);
			    printf("%s\n", tmp1); return;}
    ;
/*
    |	lines NL
    |
    ;
*/
function_definition_list :
	function_definition	{   
				    memset(tmp1, 0, sizeof(char)*Max_length_of_string);
				    pop_from_stack(&fun, tmp1);
                                    push_to_stack(&fun_l, tmp1);
				}
    |	function_definition_list function_definition	{

				    memset(tmp1, 0, sizeof(char)*Max_length_of_string);
				    memset(tmp2, 0, sizeof(char)*Max_length_of_string);
				    memset(tmp3, 0, sizeof(char)*Max_length_of_string);
				    pop_from_stack(&fun, tmp1);
				    pop_from_stack(&fun_l, tmp2);
				    sprintf(tmp3, "%s\n%s",tmp2, tmp1);
                                    push_to_stack(&fun_l, tmp3);

							}
    ;


function_definition :
	return_type variable parameter_list  compound_statement { 
                                        memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp2, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp4, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp5, 0, sizeof(char)*Max_length_of_string);
                                        pop_from_stack(&return_t, tmp1);
                                        pop_from_stack(&var, tmp2);
                                        pop_from_stack(&param_l, tmp3);
                                        pop_from_stack(&stat_c, tmp4);
					if(strcmp(tmp2, "main") == 0 && strcmp(tmp3, " ") == 0)
					    sprintf(tmp5,"public static %s %s (String[] arg) %s", tmp1, tmp2, tmp4);
					else
					    sprintf(tmp5,"public static %s %s (%s) %s", tmp1, tmp2, tmp3, tmp4);
                                        push_to_stack(&fun, tmp5);

								} 
    ;

return_type : 
	type_specifier	{
                                        memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                        pop_from_stack(&type, tmp1);
                                        sprintf(tmp3,"%s", tmp1);
                                        push_to_stack(&return_t, tmp3);
			}
    |			{
                                        memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                        sprintf(tmp3,"void");
                                        push_to_stack(&return_t, tmp3);

			}
    ;

parameter_list:
    	parameter_list parameter{
                                        memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp2, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                        pop_from_stack(&param, tmp2);
                                        pop_from_stack(&param_l, tmp1);
                                        sprintf(tmp3,"%s, %s", tmp1, tmp2);
                                        push_to_stack(&param_l, tmp3);

				}

    | parameter	{
                                        memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                        pop_from_stack(&param, tmp1);
                                        sprintf(tmp3,"%s", tmp1);
                                        push_to_stack(&param_l, tmp3);

			}
    |	{
                                        memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                        sprintf(tmp3," ");
                                        push_to_stack(&param_l, tmp3);

	}
    ;

parameter:
    type_specifier argument_expression_list ';' {
					memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp2, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp4, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp5, 0, sizeof(char)*Max_length_of_string);
                                        pop_from_stack(&arg, tmp2);
                                        pop_from_stack(&type, tmp1);
					token = strtok (tmp2," ,");
					while(token != NULL){
					    if(token[strlen(token)-1] == ']'){
						for(i = 0 ;  i < strlen(token) && token[i] != '['; i++)
						    array_id[i] = token[i];
						sprintf(tmp3, "%s[] %s", tmp1, array_id);
					    }else
						sprintf(tmp3, "%s %s ", tmp1, token);
					    sprintf(tmp4, "%s", tmp5);
					    sprintf(tmp5, "%s, %s", tmp4, tmp3);
					    token = strtok (NULL," ,");
					}
					tmp5[0] = ' ';					
                                        push_to_stack(&param, tmp5);
					    }
    ;


expr : assignment_expr  {   memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                            pop_from_stack(&assign, tmp1);
                            push_to_stack(&expr_stack, tmp1);
                        }
    |	expr ',' assignment_expr    {	memset(tmp1, 0, sizeof(char)*Max_length_of_string);
					memset(tmp2, 0, sizeof(char)*Max_length_of_string);
					memset(tmp3, 0, sizeof(char)*Max_length_of_string);
					pop_from_stack(&assign, tmp2);
					pop_from_stack(&expr_stack, tmp1);
					sprintf(tmp3,"%s,%s", tmp1, tmp2);
					push_to_stack(&expr_stack, tmp3);

				    }
    ;

statement : 
     selection_statement  {	memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                pop_from_stack(&stat_s_stack, tmp1);
                                sprintf(tmp3,"%s", tmp1);
                                push_to_stack(&stat, tmp3);}
    | expression_statement {	memset(tmp1, 0, sizeof(char)*Max_length_of_string);
			        pop_from_stack(&expr_s_stack, tmp1);
				sprintf(tmp3,"%s", tmp1);
				push_to_stack(&stat, tmp3);
			    }
    | compound_statement    {
				memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                pop_from_stack(&stat_c, tmp1);
                                sprintf(tmp3,"%s", tmp1);
                                push_to_stack(&stat, tmp3);
			    }
    | iteration_statement   {
				memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                pop_from_stack(&stat_i_stack, tmp1);
                                sprintf(tmp3,"%s", tmp1);
                                push_to_stack(&stat, tmp3);

			    }
    | jump_statement	    {
				memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                pop_from_stack(&stat_j, tmp1);
                                sprintf(tmp3,"%s", tmp1);
                                push_to_stack(&stat, tmp3);

			    }

    ;



jump_statement :
        RETURN ';'	{
                            memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                            sprintf(tmp3, "return ;");
                            push_to_stack(&stat_j, tmp3);

			} 
        | RETURN expr ';' {
				    memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                    memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                    pop_from_stack(&expr_stack, tmp1);
                                    sprintf(tmp3, "return %s;", tmp1);
                                    push_to_stack(&stat_j, tmp3);


				}
       ; 


compound_statement 
        : '{' '}'   {
			memset(tmp1, 0, sizeof(char)*Max_length_of_string);
			sprintf(tmp1, "{}");
                        push_to_stack(&stat_c, tmp1); 

		    }
	| '{' block_item_list '}' {   memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                            memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                            pop_from_stack(&block_l_stack, tmp1);
                                            sprintf(tmp3, "{\n%s\n}", tmp1);
                                            push_to_stack(&stat_c, tmp3);
                                        }

	;
block_item_list : 
	block_item {   memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                            pop_from_stack(&block_stack, tmp1);
                                            push_to_stack(&block_l_stack, tmp1);
                                        }

    |	block_item_list block_item{   memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                            memset(tmp2, 0, sizeof(char)*Max_length_of_string);
                                            memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                            pop_from_stack(&block_stack, tmp1);
                                            pop_from_stack(&block_l_stack, tmp2);
                                            sprintf(tmp3, "%s%s", tmp2, tmp1);
                                            push_to_stack(&block_l_stack, tmp3);
                                        }
 
    ;
block_item :
	statement_list {
                                        memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                        pop_from_stack(&stat_l, tmp1);
                                        sprintf(tmp3,"%s", tmp1);
                                        push_to_stack(&block_stack, tmp3);
			}

    |	variable_declaration_list   {	    memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                            memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                            pop_from_stack(&declaration_l, tmp1);
                                            sprintf(tmp3, "%s", tmp1);
                                            push_to_stack(&block_stack, tmp3);
                                        }

    ;

/*
        | '{' statement_list '}'    {
					memset(tmp1, 0, sizeof(char)*Max_length_of_string);
					pop_from_stack(&stat_l, tmp1);
					sprintf(tmp3,"{%s}", tmp1);
					push_to_stack(&stat_c, tmp3);
				    }
    | '{' variable_declaration_list '}' {   memset(tmp1, 0, sizeof(char)*Max_length_of_string);
					    memset(tmp3, 0, sizeof(char)*Max_length_of_string);
	                                    pop_from_stack(&declaration_l, tmp1);
					    sprintf(tmp3, "{%s}", tmp1);
		                            push_to_stack(&stat_c, tmp3);
			                }

    | '{' variable_declaration_list statement_list '}' {    memset(tmp1, 0, sizeof(char)*Max_length_of_string);
							    memset(tmp2, 0, sizeof(char)*Max_length_of_string);
							    memset(tmp3, 0, sizeof(char)*Max_length_of_string);
							    pop_from_stack(&declaration_l, tmp1);
							    pop_from_stack(&stat_l, tmp2);
							    sprintf(tmp3, "{%s%s}", tmp1, tmp2);
							    push_to_stack(&stat_c, tmp3);
							}

        ; 
*/
statement_list 
        : statement	{
			    memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                            pop_from_stack(&stat, tmp1);
                            sprintf(tmp3,"%s", tmp1);
                            push_to_stack(&stat_l, tmp3);		
			}
        | statement_list statement {
				memset(tmp1, 0, sizeof(char)*Max_length_of_string);
				memset(tmp2, 0, sizeof(char)*Max_length_of_string);
				memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                            pop_from_stack(&stat_l, tmp1);
                            pop_from_stack(&stat, tmp2);
                            sprintf(tmp3,"%s%s", tmp1, tmp2);
                            push_to_stack(&stat_l, tmp3);
			    }

        ; 


expression_statement 
    : ';'   {	memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                sprintf(tmp1,";\n");
                push_to_stack(&expr_s_stack, tmp1);

	    }
    | expr ';'	{   memset(tmp1, 0, sizeof(char)*Max_length_of_string);
		    memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                    pop_from_stack(&expr_stack, tmp1);
                    sprintf(tmp3,"%s;\n", tmp1);
                    push_to_stack(&expr_s_stack, tmp3);
		}
    ;


iteration_statement 
        : FOR '(' expression_statement expression_statement ')' statement   {
					memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp2, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp4, 0, sizeof(char)*Max_length_of_string);
                                        pop_from_stack(&expr_s_stack, tmp1);
                                        pop_from_stack(&expr_s_stack, tmp2);
                                        pop_from_stack(&stat, tmp3);
                                        sprintf(tmp4, "for(%s %s)\n%s", tmp2, tmp1, tmp3);
                                        push_to_stack(&stat_i_stack, tmp4);

									    }
        | FOR '(' expression_statement expression_statement expr ')' statement	{
					memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp2, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp4, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp5, 0, sizeof(char)*Max_length_of_string);
                                        pop_from_stack(&expr_s_stack, tmp1);
                                        pop_from_stack(&expr_s_stack, tmp2);
                                        pop_from_stack(&expr_stack, tmp3);
                                        pop_from_stack(&stat, tmp4);
                                        sprintf(tmp5, "for(%s %s %s)\n%s", tmp2, tmp1, tmp3, tmp4);
                                        push_to_stack(&stat_i_stack, tmp5);
											}
        ;     




selection_statement 
        : IF '(' expr ')' statement   {	memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp2, 0, sizeof(char)*Max_length_of_string);
                                        memset(tmp3, 0, sizeof(char)*Max_length_of_string);
					pop_from_stack(&expr_stack, tmp1);
                                        pop_from_stack(&stat, tmp2);
                                        sprintf(tmp3, "if(%s)\n%s", tmp1, tmp2);
                                        push_to_stack(&stat_s_stack, tmp3);
					}

        | IF '(' expr ')' statement ELSE statement    {	memset(tmp1, 0, sizeof(char)*Max_length_of_string);
								memset(tmp2, 0, sizeof(char)*Max_length_of_string);
								memset(tmp3, 0, sizeof(char)*Max_length_of_string);
								memset(tmp4, 0, sizeof(char)*Max_length_of_string);
								pop_from_stack(&expr_stack, tmp1);
								pop_from_stack(&stat, tmp2);
								pop_from_stack(&stat, tmp3);
								sprintf(tmp4, "if(%s)\n%s\nelse\n%s", tmp1, tmp3, tmp2);
								push_to_stack(&stat_s_stack, tmp4);
							    } 

      ; 

variable_declaration_list : variable_declaration {  memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                                    memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                                        pop_from_stack(&declaration, tmp1);
                                                        sprintf(tmp3, "%s", tmp1);
                                                        push_to_stack(&declaration_l, tmp3);

						}
    | variable_declaration_list variable_declaration {  memset(tmp1, 0, sizeof(char)*Max_length_of_string);
							memset(tmp2, 0, sizeof(char)*Max_length_of_string);
							memset(tmp3, 0, sizeof(char)*Max_length_of_string);
							pop_from_stack(&declaration, tmp1);
							pop_from_stack(&declaration_l, tmp2);
							sprintf(tmp3, "%s%s", tmp2, tmp1);
							push_to_stack(&declaration_l, tmp3);

							}
    ;


variable_declaration : type_specifier init_declarator_list';' {	memset(tmp1, 0, sizeof(char)*Max_length_of_string);
								memset(tmp2, 0, sizeof(char)*Max_length_of_string);
								memset(tmp3, 0, sizeof(char)*Max_length_of_string);
								memset(tmp4, 0, sizeof(char)*Max_length_of_string);
								memset(tmp5, 0, sizeof(char)*Max_length_of_string);
								memset(array_id, 0, sizeof(char)*Max_length_of_string);
								pop_from_stack(&declaration, tmp1);
								strcpy(tmp5,tmp1);
								pop_from_stack(&type, tmp2);
								token = strtok (tmp5," ,");
								while (token != NULL){
								    if(token[strlen(token)-1] == ']'){
									for(i = 0 ; i < strlen(token) && token[i] != '[' ; i++)
									    array_id[i] = token[i];
									token[strlen(token)-1] = '\0'; 
									sscanf((token+i+1), "%d", &array_size);
									sprintf(tmp3, "%s[]  %s = new %s[%d] ;\n", tmp2, array_id, tmp2, array_size);
									sprintf(tmp4,"%s %s ",tmp4,tmp3);
									for (i=0; i< array_size; i++){
						    sprintf(tmp3, "%s[%d] = new %s() ;\n Mat.addNode(%s[%d]);\n",array_id, i, tmp2, array_id, i);
						    sprintf(tmp4,"%s %s ",tmp4,tmp3);
					    				}
								    }else {
									if(strcmp(tmp2, "int") != 0){
									    if(strcmp(tmp2, "MDoc") != 0)
						    sprintf(tmp3, "%s  %s = new %s() ;\n Mat.addNode(%s);\n ", tmp2, token, tmp2, token);
									    else
								sprintf(tmp3, "%s  %s = new %s();\n Mat.initMDoc(%s);\n", tmp2, token, tmp2, token);
									    sprintf(tmp4,"%s %s ",tmp4,tmp3);
									}else
									{
									    sprintf(tmp3, "%s  %s ;\n", tmp2, token);
                                                                            sprintf(tmp4,"%s %s ",tmp4,tmp3);

									}
								    }
								    token = strtok (NULL," ,");
								}
								push_to_stack(&declaration,tmp4);
							       };

init_declarator_list:	variable    {	memset(tmp1, 0, sizeof(char)*Max_length_of_string);
					pop_from_stack(&var, tmp1);
					push_to_stack(&declaration,tmp1);
				    }
    |	init_declarator_list','variable{    memset(tmp1, 0, sizeof(char)*Max_length_of_string);
					    memset(tmp2, 0, sizeof(char)*Max_length_of_string);
					    memset(tmp3, 0, sizeof(char)*Max_length_of_string);
					    pop_from_stack(&var, tmp1);
					    pop_from_stack(&declaration, tmp2);
					    sprintf(tmp3, "%s, %s", tmp2, tmp1);
					    push_to_stack(&declaration,tmp3);
					}
    ;
										

type_specifier :    TYPE {	memset(tmp3, 0, sizeof(char)*Max_length_of_string);
				sprintf(tmp3, "%s", yylval);
				if (strcmp("#",tmp3)==0){
				    sprintf(tmp3,"int");
				}else if (strcmp("doc",tmp3)==0){
				    sprintf(tmp3,"MDoc");
				}else if (strcmp("pic",tmp3)==0){
				    sprintf(tmp3,"MPic");
				}else if (strcmp("obj",tmp3)==0){
				    sprintf(tmp3,"MObject");
				}else if (strcmp("string",tmp3)==0){
				    sprintf(tmp3,"String");
				}else if (strcmp("label",tmp3)==0){
				    sprintf(tmp3,"MLabel");
				}
				push_to_stack(&type, tmp3);
			    }
		;
assignment_expr : variable '=' assignment_expr {	memset(tmp1, 0, sizeof(char)*Max_length_of_string);
							memset(tmp2, 0, sizeof(char)*Max_length_of_string);
							memset(tmp3, 0, sizeof(char)*Max_length_of_string);
							pop_from_stack(&var, tmp1);
							pop_from_stack(&assign, tmp2);
							sprintf(tmp3, "%s = %s", tmp1, tmp2);
							push_to_stack(&assign, tmp3);
						    }
    | logic_expr    {	memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                        pop_from_stack(&logic_stack, tmp1);
                        push_to_stack(&assign, tmp1);
                    }
    ;
/*
re_assignment_expr : assignment_expr
    | logic_expr	{	memset(tmp1, 0, sizeof(char)*Max_length_of_string);
				pop_from_stack(&logic_stack, tmp1);
				push_to_stack(&assign, tmp1);
			}

    ;
*/
logic_expr: logic_expr OR_OP logic_expr	{   memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                            memset(tmp2, 0, sizeof(char)*Max_length_of_string);
                                            memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                            pop_from_stack(&logic_stack, tmp2);
                                            pop_from_stack(&logic_stack, tmp1);
                                            sprintf(tmp3, "%s || %s", tmp1, tmp2);
                                            push_to_stack(&logic_stack, tmp3);
					}
        | logic_expr AND_OP logic_expr	{   memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                            memset(tmp2, 0, sizeof(char)*Max_length_of_string);
                                            memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                            pop_from_stack(&logic_stack, tmp2);
                                            pop_from_stack(&logic_stack, tmp1);
                                            sprintf(tmp3, "%s && %s", tmp1, tmp2);
                                            push_to_stack(&logic_stack, tmp3);
					}
	| logic_expr EQ_OP logic_expr	{   memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                            memset(tmp2, 0, sizeof(char)*Max_length_of_string);
                                            memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                            pop_from_stack(&logic_stack, tmp2);
                                            pop_from_stack(&logic_stack, tmp1);
                                            sprintf(tmp3, "%s == %s", tmp1, tmp2);
                                            push_to_stack(&logic_stack, tmp3);
					}
	| logic_expr NE_OP logic_expr	{       memset(tmp1, 0, sizeof(char)*Max_length_of_string);
						memset(tmp2, 0, sizeof(char)*Max_length_of_string);
						memset(tmp3, 0, sizeof(char)*Max_length_of_string);
						pop_from_stack(&logic_stack, tmp2);
						pop_from_stack(&logic_stack, tmp1);
						sprintf(tmp3, "%s != %s", tmp1, tmp2);
						push_to_stack(&logic_stack, tmp3);
					}
	| logic_expr '>' logic_expr {       memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                            memset(tmp2, 0, sizeof(char)*Max_length_of_string);
                                            memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                            pop_from_stack(&logic_stack, tmp2);
                                            pop_from_stack(&logic_stack, tmp1);
                                            sprintf(tmp3, "%s > %s", tmp1, tmp2);
                                            push_to_stack(&logic_stack, tmp3);
                                    }
	| logic_expr '<' logic_expr {       memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                            memset(tmp2, 0, sizeof(char)*Max_length_of_string);
                                            memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                            pop_from_stack(&logic_stack, tmp2);
                                            pop_from_stack(&logic_stack, tmp1);
                                            sprintf(tmp3, "%s < %s", tmp1, tmp2);
                                            push_to_stack(&logic_stack, tmp3);
                                    } 
	| logic_expr GE_OP logic_expr	{       memset(tmp1, 0, sizeof(char)*Max_length_of_string);
			                        memset(tmp2, 0, sizeof(char)*Max_length_of_string);
						memset(tmp3, 0, sizeof(char)*Max_length_of_string);
						pop_from_stack(&logic_stack, tmp2);
						pop_from_stack(&logic_stack, tmp1);
						sprintf(tmp3, "%s >= %s", tmp1, tmp2);
						push_to_stack(&logic_stack, tmp3);
					}
	| logic_expr LE_OP logic_expr	{       memset(tmp1, 0, sizeof(char)*Max_length_of_string);
			                        memset(tmp2, 0, sizeof(char)*Max_length_of_string);
						memset(tmp3, 0, sizeof(char)*Max_length_of_string);
						pop_from_stack(&logic_stack, tmp2);
						pop_from_stack(&logic_stack, tmp1);
						sprintf(tmp3, "%s <= %s", tmp1, tmp2);
						push_to_stack(&logic_stack, tmp3);
					}
	| arithmetc_expr    {	memset(tmp1, 0, sizeof(char)*Max_length_of_string);
				pop_from_stack(&arith, tmp1);
				push_to_stack(&logic_stack, tmp1);
			    }
	;


arithmetc_expr : arithmetc_expr '+' arithmetc_expr	{   memset(tmp1, 0, sizeof(char)*Max_length_of_string);
			    memset(tmp2, 0, sizeof(char)*Max_length_of_string);
			    memset(tmp3, 0, sizeof(char)*Max_length_of_string);
			    pop_from_stack(&arith, tmp2);
			    pop_from_stack(&arith, tmp1);
			    sprintf(tmp3, "%s + %s", tmp1, tmp2);
			    push_to_stack(&arith, tmp3); 
			}
    | arithmetc_expr '-' arithmetc_expr {	memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                        memset(tmp2, 0, sizeof(char)*Max_length_of_string);
                        memset(tmp3, 0, sizeof(char)*Max_length_of_string);
			pop_from_stack(&arith, tmp2);
                        pop_from_stack(&arith, tmp1);
                        sprintf(tmp3, "%s - %s", tmp1, tmp2);
                        push_to_stack(&arith, tmp3);
		    }
    | arithmetc_expr '*' arithmetc_expr {	memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                        memset(tmp2, 0, sizeof(char)*Max_length_of_string);
                        memset(tmp3, 0, sizeof(char)*Max_length_of_string);
			pop_from_stack(&arith, tmp2);
                        pop_from_stack(&arith, tmp1);
                        sprintf(tmp3, "%s * %s", tmp1, tmp2);
                        push_to_stack(&arith, tmp3); 
		    }
    | arithmetc_expr '/' arithmetc_expr {	memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                        memset(tmp2, 0, sizeof(char)*Max_length_of_string);
                        memset(tmp3, 0, sizeof(char)*Max_length_of_string);
			pop_from_stack(&arith, tmp2);
			pop_from_stack(&arith, tmp1);
			sprintf(tmp3, "%s / %s", tmp1, tmp2);
			push_to_stack(&arith, tmp3);
		    }
    | arithmetc_expr '%' arithmetc_expr {	memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                        memset(tmp2, 0, sizeof(char)*Max_length_of_string);
                        memset(tmp3, 0, sizeof(char)*Max_length_of_string);
			pop_from_stack(&arith, tmp2);
			pop_from_stack(&arith, tmp1);
			sprintf(tmp3, "%s %s %s", tmp1,"%" ,tmp2);
			push_to_stack(&arith, tmp3);
		    }
    | '!' arithmetc_expr %prec UMINUS   {   memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                                            memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                                            pop_from_stack(&arith, tmp1);
                                            sprintf(tmp3, " !%s ", tmp1);
                                            push_to_stack(&arith, tmp3);
                                        }

    | '-' arithmetc_expr %prec UMINUS {   memset(tmp1, 0, sizeof(char)*Max_length_of_string);
				memset(tmp3, 0, sizeof(char)*Max_length_of_string);
				pop_from_stack(&arith, tmp1);
				sprintf(tmp3, " -%s ", tmp1);
				push_to_stack(&arith, tmp3);
			    }
    | variable  {	memset(tmp1, 0, sizeof(char)*Max_length_of_string);
			memset(tmp3, 0, sizeof(char)*Max_length_of_string);
			pop_from_stack(&var, tmp1);
			sprintf(tmp3, "%s", tmp1);
			push_to_stack(&arith, tmp3);
		}
    ;
atrbut :    ATTRIBUTE {   memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                            sprintf(tmp3, "%s", yylval);
                            push_to_stack(&atrb, tmp3);
                        }
    ;
argument_expression_list : logic_expr	{   memset(tmp3, 0, sizeof(char)*Max_length_of_string);
					    pop_from_stack(&logic_stack, tmp3);
					    push_to_stack(&arg, tmp3);

					}
    | argument_expression_list ',' logic_expr	{   memset(tmp1, 0, sizeof(char)*Max_length_of_string);
						    memset(tmp3, 0, sizeof(char)*Max_length_of_string);
						    memset(tmp2, 0, sizeof(char)*Max_length_of_string);
						    pop_from_stack(&arg, tmp1);
						    pop_from_stack(&logic_stack, tmp2);
						    sprintf(tmp3, "%s,%s", tmp1, tmp2);
						    push_to_stack(&arg, tmp3);
						}
variable    : IDENTIFIER    {	memset(tmp3, 0, sizeof(char)*Max_length_of_string);
				memset(tmp1, 0, sizeof(char)*Max_length_of_string);
				sprintf(tmp3, "%s", yylval);
				if(strcmp("INNERMIDDLE",tmp3)==0 || strcmp("INNERTOP",tmp3)==0 || strcmp("INNERLEFT",tmp3)== 0)
				    sprintf(tmp1, "MDirection.%s", tmp3);
				else if (strcmp("INNERRIGHT",tmp3)==0 || strcmp("INNERDOWN",tmp3)==0 || strcmp("INNERTOPLEFT",tmp3)== 0)
				    sprintf(tmp1, "MDirection.%s", tmp3);
				else if (strcmp("INNERDOWNRIGHT",tmp3)==0 || strcmp("INNERDOWNLEFT",tmp3)==0 || strcmp("INNERTOPRIGHT",tmp3)== 0)
				    sprintf(tmp1, "MDirection.%s", tmp3);
				else if (strcmp("right",tmp3)==0 || strcmp("up",tmp3)==0 || strcmp("left",tmp3)== 0 || strcmp("down",tmp3)== 0)
				    sprintf(tmp1, "MDirection.%s", tmp3);
				else	
				    sprintf(tmp1, "%s", tmp3);
				push_to_stack(&var, tmp1);
			    }	     
	    | variable '.' atrbut  {	    memset(tmp1, 0, sizeof(char)*Max_length_of_string);
					    memset(tmp3, 0, sizeof(char)*Max_length_of_string);
					    memset(tmp2, 0, sizeof(char)*Max_length_of_string);
					    pop_from_stack(&var, tmp1);
					    pop_from_stack(&atrb, tmp2);
					    if(strcmp("font_size", tmp2) == 0)
						sprintf(tmp3, "%s.fontSize", tmp1);
					    else if(strcmp("font_type", tmp2) == 0)
						sprintf(tmp3, "%s.fontType", tmp1);	
					    else if(strcmp("default_distance", tmp2) == 0)
						sprintf(tmp3, "%s.defaultdistance", tmp1);	
					    else if(strcmp("default_font_type", tmp2) == 0)
						sprintf(tmp3, "%s.fontType", tmp1);	
					    else if(strcmp("default_font_size", tmp2) == 0)
						sprintf(tmp3, "%s.fontSize", tmp1);
					    else if(strcmp("z-axis", tmp2) == 0)
						sprintf(tmp3, "%s.zaxis", tmp1);
					    else
						sprintf(tmp3, "%s.%s", tmp1, tmp2);
					    push_to_stack(&var, tmp3);
					}

	    | variable '[' arithmetc_expr ']' {   memset(tmp1, 0, sizeof(char)*Max_length_of_string);
					memset(tmp2, 0, sizeof(char)*Max_length_of_string);
					memset(tmp3, 0, sizeof(char)*Max_length_of_string);
					pop_from_stack(&arith, tmp1);
					pop_from_stack(&var, tmp2);
					sprintf(tmp3, "%s[%s]", tmp2, tmp1);
					push_to_stack(&var, tmp3);
				    }

	    | variable '(' ')'  {   memset(tmp3, 0, sizeof(char)*Max_length_of_string);
				    memset(tmp1, 0, sizeof(char)*Max_length_of_string);
				    pop_from_stack(&var, tmp1);
				    if((strcmp(tmp1, "from") == 0) || (strcmp(tmp1, "degree") == 0) || (strcmp(tmp1, "dist") == 0)){
                                        if((strcmp(tmp1, "dist") == 0))
					    sprintf(tmp3, "Mat.distance()", tmp1);
					else
					    sprintf(tmp3, "Mat.%s()", tmp1);
                                    }else if((strcmp(tmp1, "poly") == 0) || (strcmp(tmp1, "text") == 0) || (strcmp(tmp1, "layout") == 0)) {
                                        if((strcmp(tmp1, "layout") == 0))
                                            sprintf(tmp3, "Mat.%s1()", tmp1);
                                        else
                                            sprintf(tmp3, "Mat.%s()", tmp1);
                                    }else
					sprintf(tmp3, "%s()", tmp1);
				    push_to_stack(&var, tmp3);
				}
	    | variable '('argument_expression_list ')'  {   memset(tmp3, 0, sizeof(char)*Max_length_of_string);
				    memset(tmp2, 0, sizeof(char)*Max_length_of_string);
				    memset(tmp1, 0, sizeof(char)*Max_length_of_string);
				    pop_from_stack(&var, tmp1);
				    pop_from_stack(&arg, tmp2);
				    if((strcmp(tmp1, "from") == 0) || (strcmp(tmp1, "degree") == 0) || (strcmp(tmp1, "dist") == 0)){
                                        if((strcmp(tmp1, "dist") == 0))
					    sprintf(tmp3, "Mat.distance(%s)", tmp2);
					else
					    sprintf(tmp3, "Mat.%s(%s)", tmp1, tmp2);
				    }else if((strcmp(tmp1, "poly") == 0) || (strcmp(tmp1, "text") == 0) || (strcmp(tmp1, "layout") == 0)) {
					if((strcmp(tmp1, "layout") == 0))
					    sprintf(tmp3, "Mat.%s1(%s)", tmp1, tmp2);
					else
					    sprintf(tmp3, "Mat.%s(%s)", tmp1, tmp2);
				    }else
					sprintf(tmp3, "%s(%s)", tmp1, tmp2);
				    push_to_stack(&var, tmp3);
				}
	    | CONSTANT	{   memset(tmp3, 0, sizeof(char)*Max_length_of_string);
			    sprintf(tmp3, "%s", yylval);
			    push_to_stack(&var, tmp3);
			}

	    | STRING_LITERAL	{
				    memset(tmp3, 0, sizeof(char)*Max_length_of_string);
	                            sprintf(tmp3, "%s", yylval);
		                    push_to_stack(&var, tmp3);
				}

	    | '(' logic_expr ')'  {     memset(tmp1, 0, sizeof(char)*Max_length_of_string);
                        memset(tmp3, 0, sizeof(char)*Max_length_of_string);
                        pop_from_stack(&logic_stack, tmp1);
                        sprintf(tmp3, "( %s )", tmp1);
                        push_to_stack(&var, tmp3);
                    }


%%


int yywrap(void){
    return 0;
}
void yyerror(char const *s){
    fprintf(stderr, "%s\n", s);
}
int main(void){
    init_stack(&arith);
    init_stack(&var);
    init_stack(&arg);
    init_stack(&assign);
    init_stack(&atrb);
    init_stack(&expr_stack);
    init_stack(&declaration);
    init_stack(&type);
    init_stack(&block_stack);
    init_stack(&block_l_stack);
    init_stack(&logic_stack);
    init_stack(&stat);
    init_stack(&stat_l);
    init_stack(&stat_j);
    init_stack(&stat_c);
    init_stack(&stat_s_stack);
    init_stack(&stat_i_stack);
    init_stack(&expr_s_stack);
    init_stack(&fun);
    init_stack(&fun_l);
    init_stack(&param);
    init_stack(&param_l);
    init_stack(&return_t);
    printf("package tests;\nimport mat.*;\nimport types.*;\npublic class test {\n");
    yyparse();
    printf("\n}\n");

    return 0;
}
